﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace WinForms_path
{
   
    public  class AStarNode
    {
        
        public AStarNode(Point loc, AStarNode previous, int _costG, int _costH)
        {
            this.location = loc;
            this.previousNode = previous;
            this.costG = _costG;
            this.costH = _costH;
        }
       

        private Point location = new Point(0, 0);
        /// <summary>
        /// Location 节点所在的位置，其X值代表ColumnIndex，Y值代表LineIndex
        /// </summary>
        public Point Location
        {
            get { return location; }
        }
       
        private AStarNode previousNode = null;
        /// <summary>
        /// PreviousNode 父节点，即是由哪个节点导航到当前节点的。
        /// </summary>
        public AStarNode PreviousNode
        {
            get { return previousNode; }
        }
       
        /// <summary>
        /// CostF 从起点导航经过本节点然后再到目的节点的估算总代价。
        /// </summary>
        public int CostF
        {
            get
            {
                return this.costG + this.costH;
            }
        }
       
        private int costG = 0;
        /// <summary>
        /// CostG 从起点导航到本节点的代价。
        /// </summary>
        public int CostG
        {
            get { return costG; }
        }
        

        
        private int costH = 0;
        /// <summary>
        /// CostH 使用启发式方法估算的从本节点到目的节点的代价。
        /// </summary>
        public int CostH
        {
            get { return costH; }
        }
        

        
        /// <summary>
        /// ResetPreviousNode 当从起点到达本节点有更优的路径时，调用该方法采用更优的路径。
        /// </summary>        
        public void ResetPreviousNode(AStarNode previous, int _costG)
        {
            this.previousNode = previous;
            this.costG = _costG;
        }
       

        public override string ToString()
        {
            return this.location.ToString();
        }

    }    
    /// <summary>
    /// 我们假设，从某个节点出发，最多可以有8个方向移动，这8个方向定义为CompassDirections：
    /// </summary>
    public enum CompassDirections

    {
        NotSet = 0,
        North = 1, //UP
        NorthEast = 2, //UP Right
        East = 3,
        SouthEast = 4,
        South = 5,
        SouthWest = 6,
        West = 7,
        NorthWest = 8
    };
    /// <summary>
    /// ICostGetter 获取从当前节点向某个方向移动时的代价。
    /// </summary>
    public interface ICostGetter
    {
        int GetCost(Point currentNodeLoaction, CompassDirections moveDirection);
    }
    /// <summary>
    /// SimpleCostGetter ICostGetter接口的简化实现。直线代价为10， 斜线为14。
    /// </summary>
    public class SimpleCostGetter : ICostGetter
    {
        #region ICostGetter 成员
        public int GetCost(Point currentNodeLoaction, CompassDirections moveDirection)
        {
            if (moveDirection == CompassDirections.NotSet)
            {
                return 0;
            }
            if (moveDirection == CompassDirections.East || moveDirection 
                == CompassDirections.West || moveDirection
                == CompassDirections.South || moveDirection 
                == CompassDirections.North)
            {
                return 10;
            }
            return 14;
        }
        #endregion
    }



    /// <summary>
    /// RoutePlanData 用于封装一次路径规划过程中的规划信息。
    /// </summary>
    public class RoutePlanData
    {
        #region CellMap
        private Rectangle cellMap;
        /// <summary>
        /// CellMap 地图的矩形大小。经过单元格标准处理。
        /// </summary>
        public Rectangle CellMap
        {
            get { return cellMap; }
        }
        #endregion

        #region ClosedList
        private IList<AStarNode> closedList = new List<AStarNode>();

        /// <summary>
        /// ClosedList 关闭列表，即存放已经遍历处理过的节点。
        /// </summary>
        public IList<AStarNode> ClosedList
        {
            get { return closedList; }
        }
        #endregion

        #region OpenedList
        private IList<AStarNode> openedList = new List<AStarNode>();
        /// <summary>
        /// OpenedList 开放列表，即存放已经开发但是还未处理的节点。
        /// </summary>
        public IList<AStarNode> OpenedList
        {
            get { return openedList; }
        }
        #endregion

        #region Destination
        private Point destination;
        /// <summary>
        /// Destination 目的节点的位置。
        /// </summary>
        public Point Destination
        {
            get { return destination; }
        }
        #endregion

        #region Ctor
        public RoutePlanData(Rectangle map, Point _destination)
        {
            this.cellMap = map;
            this.destination = _destination;
        }
        #endregion
    }

}
